--  ---------------------------------------------------------------------------
--  @File: document.ads
--
--  @Project: LiberAda
--  @Version: 1.0
--  @Created: 2009-10-13
--  @Author:  Ivan Bogicevic
--
--  @Description:
--    A document is the resulting documentation file of an ada source file.
--    All code elements of the source file are stored here in a defined order.
--    Both the source code (all tokens in correct order) and sorted additional
--    information (e.g. the procedure/function names with their parameters) are
--    transformed here to the resulting html document.
--
--  @Modifications:
--    +2009-11-17 MK: Restructured the document model and document
--      generation.
--    +2011-07-14 JT: Added table of contents support
--  ---------------------------------------------------------------------------
with Ada.Strings.Unbounded;
with Ada_Tokenizer;

with Part;
with Comment_Parser;

package Document is

   package ASU renames Ada.Strings.Unbounded;

   --  ----------------------------------------------------------------------
   --  @Type: Document_Type
   --  @Purpose: Type for the document model.
   type Document_Type is tagged private;

   --  ----------------------------------------------------------------------
   --  @Procedure: Initialize
   --  @Description:
   --    Initializes the document object model and creates the basic
   --    structure of a liberAda HTML documentation.
   --  @Parameter:
   --    +This: Document to initialize
   procedure Initialize (This : out Document_Type);

   --  ----------------------------------------------------------------------
   --  @Procedure: Destroy
   --  @Description:
   --    Destroys a document model by freeing all allocated resources.
   --  @Parameter:
   --    +This: Document to destroy
   procedure Destroy (This : in out Document_Type);

   --  ----------------------------------------------------------------------
   --  @Procedure: Set_In_File
   --  @Description: Sets the full path of the file that is represented
   --    by this document.
   --  @Parameter:
   --    +This: Document to set file for
   --    +In_File: The file this document represents
   procedure Set_In_File
     (This    : in out Document_Type;
      In_File : in     ASU.Unbounded_String);

   --  ----------------------------------------------------------------------
   --  @Function: Get_In_File
   --  @Description:
   --    Return the name of the file this document represents.
   --  @Parameter:
   --    +This: Document the get the in file from
   --  @Return:
   --    The name of the file this document represents
   function Get_In_File
     (This : in Document_Type) return ASU.Unbounded_String;

   --  ----------------------------------------------------------------------
   --  @Function: Get_Out_File
   --  @Description:
   --    Returns the name of the file to which this document is written.
   --    The name of the out file is derived from the in file's name.
   --  @Parameter:
   --    +This: Document to get out file for
   --  @Return:
   --    Name of the file to which this document is written.
   function Get_Out_File
     (This : in Document_Type) return ASU.Unbounded_String;

   --  ------------------------------------------------------------------------
   --  @Procedure: Add_Token
   --  @Description:
   --    Adds a token (e.g. "while") to the document. The token is written to
   --    html, its format depends on its kind (e.g. COMMENT_T is italic gray).
   --  @Parameter:
   --    +Kind: The kind of the token (e.g. DOT_T)
   --    +Value: The stringvalue of the token like it stands in the source file
   procedure Add_Token
     (This   : in out Document_Type;
      Kind   : in     Ada_Tokenizer.Token_Type;
      Value  : in     ASU.Unbounded_String);

   --  ----------------------------------------------------------------------
   --  @Procedure: Add_Comment
   --  @Description:
   --    Adds the given comment to this document.
   procedure Add_Comment
     (This    : in out Document_Type;
      Comment : in     Comment_Parser.Comment_Type);

   --  ----------------------------------------------------------------------
   --  @Procedure: Make_Table_Of_Contents
   --  @Description: Creates the linked table of contents and puts it into
   --    the TOC document part, so when outputting the document the users
   --    have easy access to types, procedures and so on.
   --
   --    This routine will link types, constants, exceptions, variables and
   --    routines as well as source code. Empty parts are skipped. When
   --    calling this procedure the table of contents is always newly
   --    generated and appended to the existing one. Make sure you call it
   --    after all parts are generated in the document.
   --
   --    TODO: clear TOC before appending stuff so this is idempotent
   --  @Parameter:
   --    +This: the document which's TOC should be generated
   procedure Make_Table_Of_Contents (This : in out Document_Type);

   --  ------------------------------------------------------------------------
   --  @Procedure: Write_HTML
   --  @Description:
   --    Writes all symbols and tokens out to the specified html file. If the
   --    file already exists, it is overwritten.
   procedure Write_HTML (This : in Document_Type);

   --  ------------------------------------------------------------------------
   --  @Function: "="
   --  @Description:
   --    Defines, that two documents are equal, if their paths to the source
   --    files are equal.
   --  @Parameter:
   --    +Left: One of the documents to check the equality with another one
   --    +Right: The other document to check the equality with
   --  @Return:
   --    True, if the paths to the source files of the documents are equal.
   function "=" (Left, Right : Document_Type) return Boolean;
   pragma Inline ("=");

private

   type Document_Type is tagged record
      --  Contains the path to the ada source file for this html document
      In_File : ASU.Unbounded_String;

      --  Root of the document
      Root : Part.Part_Type;

      --  Page title
      Title : Part.Part_Type;
      --  Page heading
      Head  : Part.Part_Type;
      --  Page content
      Content : Part.Part_Type;

      --  Special sections in the documentation
      TOC        : Part.Part_Type;
      Types      : Part.Part_Type;
      Constants  : Part.Part_Type;
      Exceptions : Part.Part_Type;
      Variables  : Part.Part_Type;
      Routines   : Part.Part_Type;
      Code       : Part.Part_Type;
   end record;

end Document;
